package com.qfedu.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.recommend.RecommendAPI;
import com.qfedu.entity.*;
import com.qfedu.mapper.ProductImgMapper;
import com.qfedu.mapper.ProductMapper;
import com.qfedu.mapper.ProductSkuMapper;
import com.qfedu.mapper.SkuDateMapper;
import com.qfedu.service.ProductService;
import com.qfedu.util.JsonUtil;
import com.qfedu.vo.*;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 作者：刘随阳
 * 时间: 2021/9/20 15:46
 * 描述：神光照耀,太白成瑞。六丙来迎,百福悠归
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private RecommendAPI recommendAPI;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private SkuDateMapper skuDateMapper;

    @Autowired
    private ProductSkuMapper productSkuMapper;

    @Autowired
    private ProductImgMapper productImgMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    @Override
    public ResultVo getIndexProduct(Integer productType) {
        try {
            //先从redis缓存中取值
            String indexProductsJson = (String) stringRedisTemplate.opsForHash().get("indexProduct",productType.toString());
            ObjectMapper om = new ObjectMapper();
            if(StringUtils.isEmpty(indexProductsJson)){
                //没取到，则从数据库取值
                List<ProductVo> indexProduct = productMapper.getIndexProduct(productType);
                if (StringUtils.isEmpty(indexProduct)){
                    //数据库也没取到，返回失败
                    return ResultVo.fail("查询失败");
                }
                //数据库取到，将数据存入redis
                String s = om.writeValueAsString(indexProduct);
                stringRedisTemplate.opsForHash().put("indexProduct",productType.toString(),s);
                return ResultVo.success("查询成功",indexProduct);
            }
            //从redis取到数据，转为集合对象
            List<ProductVo> productVos = JsonUtil.stringToList(indexProductsJson, ProductVo.class);;
            return ResultVo.success("查询成功",productVos);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return ResultVo.fail("查询失败");
    }

    @Override
    public ResultVo getProductDetail(Integer productId,String token) {
        if(!token.equals("123")){
            JwtParser parser = Jwts.parser();
            parser.setSigningKey("123456");
            Jws<Claims> claimsJws = parser.parseClaimsJws(token);
            Claims body = claimsJws.getBody();
            String id = body.getId();
            UserHobby userHobby = new UserHobby(null,Integer.parseInt(id),productId,1);
            ResultVo vo = recommendAPI.updateUserHobby(userHobby);
            System.out.println();
        }

        try {
            //先从redis缓存中取值
            String productDetailJson = (String) stringRedisTemplate.opsForHash().get("productDetail",productId.toString());
            ObjectMapper om = new ObjectMapper();
            if(StringUtils.isEmpty(productDetailJson)){
                //没取到，则从数据库取值
                //写mapper文件一直报错，没办法，只能在这一顿操作查商品详情了
                Product product = productMapper.selectByPrimaryKey(productId);

                Example example = new Example(ProductImg.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("productId",productId);
                List<ProductImg> productImgs = productImgMapper.selectByExample(example);

                Example example1 = new Example(ProductSku.class);
                Example.Criteria criteria1 = example1.createCriteria();
                criteria1.andEqualTo("skuProductId",productId);
                List<ProductSku> productSkus = productSkuMapper.selectByExample(example1);

                ArrayList<ProductSkuVo> productSkuVos = new ArrayList<>();
                for (ProductSku skus : productSkus) {
                    Example example2 = new Example(SkuDate.class);
                    Example.Criteria criteria2 = example2.createCriteria();
                    criteria2.andEqualTo("dateSkuId",skus.getSkuId());
                    List<SkuDate> skuDates = skuDateMapper.selectByExample(example2);
                    ProductSkuVo productSkuVo = new ProductSkuVo();
                    productSkuVo.setProductSku(skus);
                    productSkuVo.setSkuDates(skuDates);
                    productSkuVos.add(productSkuVo);
                }
                ProductDetailVo productDetailVo = new ProductDetailVo(product,productImgs,productSkuVos);

                if (StringUtils.isEmpty(productDetailVo)){
                    //数据库也没取到，返回失败
                    return ResultVo.fail("查询失败");
                }
                //数据库取到，将数据存入redis
                String s = om.writeValueAsString(productDetailVo);
                stringRedisTemplate.opsForHash().put("productDetail",productId.toString(),s);
                return ResultVo.success("查询成功",productDetailVo);
            }
            //从redis取到数据，转为集合对象
            ProductDetailVo productDetailVo = JsonUtil.stringToObject(productDetailJson, ProductDetailVo.class);
            return ResultVo.success("查询成功",productDetailVo);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResultVo.fail("查询失败");
    }

    @Override
    public ResultVo getOrderParams(Integer productId,Integer skuId,Integer dateId) {
        Product product = productMapper.selectByPrimaryKey(productId);
        ProductSku productSku = productSkuMapper.selectByPrimaryKey(skuId);
        SkuDate skuDate = skuDateMapper.selectByPrimaryKey(dateId);
        return ResultVo.success("查询成功",new ProductParamsVo(product,productSku,skuDate));
    }
}
